package com.example.demo.entity.base;

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description: 条件对象
 * @author: cj
 * @create: 17-03-09 17:24:03
 */
@Data
@AllArgsConstructor
public class Condition implements Serializable {

    @Resource
    public static MongoTemplate mongoTemplate;
    /**
     * and 条件
     */
    private List<QueryPara> parAndList;
    /**
     * or 条件
     */
    private List<QueryPara> parOrList;
    /**
     * 分页参数 当前页
     */
    private Integer page;
    /**
     * 分页参数 每页个数
     */
    private Integer pageSize;

    public Condition() {

    }

    public Condition(List<QueryPara> parAndList, List<QueryPara> parOrList) {
        this.parAndList = parAndList;
        this.parOrList = parOrList;
        if (CollectionUtils.isEmpty( parAndList ) && CollectionUtils.isEmpty( parOrList )) {
            throw new RuntimeException( "and和or 不能都为null" );
        } else {
            if (CollectionUtils.isEmpty( parAndList )) {
                if (CollectionUtils.isEmpty( parOrList )) {
                    throw new RuntimeException( "参数错误" );
                }
            } else {
                if (!CollectionUtils.isEmpty( parOrList )) {
                    throw new RuntimeException( "参数错误" );
                }
            }
        }
    }


    public static Condition mapToCond(Map<String, Object> map) {
        return JSON.parseObject( JSON.toJSONString( map ), Condition.class );
    }

    public static CriteriaDefinition changeCriteria(Condition condition) {

        Criteria criteria = new Criteria();
        List<QueryPara> parList;
        boolean isAnd = true;
        if (CollectionUtils.isEmpty( condition.getParAndList() )) {
            parList = condition.getParOrList();
            isAnd = false;
        } else {
            parList = condition.getParAndList();
        }
        if (isAnd) {
            for (QueryPara queryPara : parList) {
                String column = queryPara.getColumn();
                criteria = criteria.and( column );
                criteria.criteria.put( queryPara.getType(), queryPara.getValue() );
            }
        } else {
            Criteria orCriteria = new Criteria();
            List<Criteria> list = new ArrayList<>();
            for (QueryPara queryPara : parList) {
                String column = queryPara.getColumn();
                criteria = Criteria.where( column );
                criteria.criteria.put( queryPara.getType(), queryPara.getValue() );
                list.add( criteria );
            }
            Criteria[] criterias = new Criteria[list.size()];
            criteria = orCriteria.orOperator( list.toArray( criterias ) );

        }
        return criteria;
    }

    public static Query changeQuery(Condition condition) {
        Integer page = condition.getPage();
        Integer pageSize = condition.getPageSize();
        Query query;
        if (page != null) {
            query = Query.query( changeCriteria( condition ) ).skip( (page - 1) * pageSize ).limit( pageSize );
        } else {
            query = Query.query( changeCriteria( condition ) );
        }
        return query;
    }
}
